/*
 * This is the main radar class. To create new radar a object of this class have
 * to instantiate. Everything else will be handeled by this class.
 * The object will start working only afte update() function is called.
 */
package com.hitechbangla.fctu.base.radar;

import com.hitechbangla.fctu.base.AutoLockable;
import com.hitechbangla.fctu.base.Location;
import com.hitechbangla.fctu.base.LocationInteger;
import com.hitechbangla.fctu.base.aircraft.*;
import com.hitechbangla.fctu.base.weather.Cloud;
import com.hitechbangla.fctu.utility.GeneralUtil;
import com.hitechbangla.fctu.utility.enumall.AircraftPathShowOption;
import com.hitechbangla.fctu.utility.enumall.ObjectColors;
import fctu.simulator.HTB_MAIN;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.io.Serializable;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.Timer;
//import javax.swing.Timer;



/**
 *
 * @author Irteza
 */
public class Radar implements Serializable, ActionListener
{
    //htb parent

    //HTB_MAIN HTBParent;
    //Class instance variable
    transient Timer timer;
    //transient Thread t;
    private RadarType radarType;
    private RadarState radarState;
    private List<Detected> detectedList;
    private List<Aircraft> allAircraft;
    private double needleAngle;
    private long sleepTimer;
    private int cnt;
    private double coneX, coneY;
    private HashMap detectedMap = new HashMap<Integer, Detected>();
    private AutoLock autoLock;
    private List<Location> pathAircraft;   
    private AutoLockGround autoLockGround;
    private AIRadar aiRadar;   
    private AircraftListForPath aircraftListForPath;
    private AircraftPathShowOption aircraftPathShowOption;
    private List<Aircraft> ecmAircraftList;
    private EpmType epmType;
    private List<EcmDrawable> ecmDrawableList;
    private long lastEcmTime;
    private boolean radarContinue;
    private static int toggle=1;
    public static int iffControl = 0;
    /*
     * Constructor function for radar class
     */



    public void stopTimer()
    {
	timer.stop();
        timer = null;
    }
    
    public Radar(RadarType radarType, RadarState radarState, List<Aircraft> allAC) {
	//t = new Thread(this, "Radar");
	this.radarType = radarType;
	this.radarState = radarState;
	allAircraft = allAC;
	detectedList = new LinkedList<Detected>();
	needleAngle = 0.5;
	sleepTimer = 60000 / (180 * radarType.getRPM());
	cnt = 0;
	pathAircraft = new ArrayList<>();
	aiRadar = new AIRadar(16, 90, this);
	timer = new Timer((int)sleepTimer, this);
	ecmAircraftList = new ArrayList<Aircraft>();
	epmType = EpmType.NONE;
	ecmDrawableList = new ArrayList<EcmDrawable>();
	lastEcmTime = 0;
	aircraftListForPath = new AircraftListForPath();
	//mapAircraftPathList = new HashMap<String, Integer[]>(); // Here key is aircraft callsign, value is four aircraft location     
	
	//t.start();
	aircraftPathShowOption = AircraftPathShowOption.DefaultPath;
	radarContinue = true;
    }	//End of constructor

    public void addAutoLock(AutoLock autoLock) {
	this.autoLock = autoLock;
    }

    public void addAutoLockGround(AutoLockGround autoLockGround) {
	this.autoLockGround = autoLockGround;
    }

    public void actionPerformed(ActionEvent evt) {
        run();
    }
    /*
     * Start of addDetectable function
     * This function will add new aircraft in the detectable list
     */
    public void addDetectable(Aircraft a) {
	Detected detected = new Detected(a);
	aircraftListForPath.addAircraft(a.getAircraftState().getCallSign(), detected.getAcPosX(), detected.getAcPosY());
	
	////System.out.println("from radar: detected added");
	//detectedList.add(detected);
	getDetectedMap().put(a.getAircraftState().getCallSign(), detected);
	//a.getAircraftState().getListLocation().add(a.getAircraftState().getLocation());
	////System.out.println("from radar: added to the list");
	////System.out.println("from radar: callsign " + a.getAircraftState().getCallSign());
	////System.out.println("from radar: size " + getDetectedMap().size());
	pathAircraft.add(new Location(detected.getAcPosX(), detected.getAcPosY(), 0));
	
	//updateAircraftPath();
	
	////System.out.println("from radar: x - " + detected.getAcPosX() + ", y - " + detected.getAcPosY());
	//a.getAircraftState().addLocationInDefaultPath(new LocationInteger(new Integer(detected.getAcPosX()), new Integer(detected.getAcPosY())));
	////System.out.println("from radar: default path size - " + a.getAircraftState().defaultPathSize());



    }    //End of addDetectable function

    /*
     * Start of updateRadar function
     * This function will start the thread when called. The radar list will start
     * to update it's data automatically after that.
     */
    public void stopRader() {
	//if(t!=null)
	//  t = null;
	if (timer != null) {
            timer.stop();
	    timer = null;
            //timer.cancel();
	}
    }

    public void updateRadar() {
	if (timer == null) {
	    timer = new Timer((int)sleepTimer, this);
	}

        timer.start();
	////System.out.println("rabbi:" + sleepTimer);
	//timer.scheduleAtFixedRate(this, 0, sleepTimer);
	//timer.schedule(this, 1);

	//if(t == null) {
	//  t = new Thread(this, "Radar");
	// t.start();	//starting the thread
	//}

	//t.start();	//starting the thread


	//Comment out the following part to check the function //manually.	

	/*
	 while (true) {
	 coneX = radarState.getLocation().getX() + radarType.getRadarRange() * Math.cos(GeneralUtil.degreeToRadian((float) needleAngle));
	 coneY = radarState.getLocation().getY() + radarType.getRadarRange() * Math.sin(GeneralUtil.degreeToRadian((float) needleAngle));
	 HTBParent.repaint();
	 Location baseOfCone = new Location((float) coneX, (float) coneY, 0);
	 for (Aircraft ac : allAircraft) {
	 if (GeneralUtil.isLyingInCone(ac.getAircraftState().getLocation(), radarState.getLocation(), baseOfCone, radarType.getAperture())) {
	 if (ac.getAircraftState().getLocation().getZ() <= radarType.getRadarRange()) {
	 addDetectable(ac);
	 HTBParent.repaint();
	 }
	 }
	 }

	 needleAngle += radarType.getAperture();
	 if (needleAngle >= 360.0) {
	 needleAngle = (int) needleAngle % 360;
	 cnt++;
	 //System.out.println("Rotation: " + cnt);
	 }

	 } //End of while loop
	 */
    }    //End of updateRadar function

    /*
     * Implementing the run function of runnable interface
     * The update will work in this function, when a object is created this function
     * is called from constructor and updating the detected object in radar automatically.
     */
    public void run() {
	//double coneX, coneY;
	long t;
	//while (radarContinue)
        {

	    coneX = getRadarState().getLocation().getX() + getRadarType().getRadarRange() * Math.cos(GeneralUtil.degreeToRadian((float) needleAngle));
	    coneY = getRadarState().getLocation().getY() + getRadarType().getRadarRange() * Math.sin(GeneralUtil.degreeToRadian((float) needleAngle));
	    //HTB_MAIN.paintIt();
	    Location baseOfCone = new Location((float) coneX, (float) coneY, 0);
	    
	    try 
	    {
		for (Aircraft ac : allAircraft) 
		{	    
		    if (GeneralUtil.isLyingInCone(ac.getAircraftState().getLocation(), getRadarState().getLocation(), baseOfCone, getRadarType().getAperture())) 
		    {
			if (!isOutOfRange(ac)) 
			{
			    addDetectable(ac);			    			    
			    //System.out.println("from radar: size " + this.getDetectedMap().size());
			} 
			else if (isOutOfRange(ac)) 
			{
			    getDetectedMap().remove(ac.getAircraftState().getCallSign());			    
			}	
			
			//HTBParent.repaint();
			//HTB_MAIN.paintIt();
		    }
		    else
		    {
			////System.out.println("out of cone");
		    }
		}

		/*
		 needleAngle += getRadarType().getAperture();
		 if (needleAngle >= 360.0) {
		 needleAngle = (int) needleAngle % 360;
		 cnt++;
		 ////System.out.println("Rotation: " + cnt);
		 }
		 */
		needleAngle -= getRadarType().getAperture();
		if (needleAngle <= 0.0) {
		    needleAngle = (int) (needleAngle + 360) % 360;
		    cnt++;
		    ////System.out.println("Rotation: " + cnt);
		}

		//Thread.sleep((int) sleepTimer);
		//timer.wait(sleepTimer, cnt);
		////System.out.println("Thread Safe Command: " + sleepTimer);
		//Thread.sleep(1000);
		//
		t = System.currentTimeMillis();

		//System.out.println("Size of ecm aircral" + ecmAircraftList.size());
		if ((t - lastEcmTime) > 3000) {
		    lastEcmTime = t;
		    setEcmEffect();
                    
		}
//		setEcmEffect();
		HTB_MAIN.paintIt();
                //timer.wait(sleepTimer);
		//break;
	    } catch (Exception e) {
		//System.out.println("Child Interrupted");
	    }
	}
    }    //End of run function

    public void setEcmEffect() {
	//System.out.println("Inside set ecm effect");
	if (ecmAircraftList.size() == 0) {
	    return;
	} else {
	    switch (epmType) {
		case FA:
		    //updateEcmEffectForFA_EPM();
		    //updateEcmEffect();
		    for (Aircraft ac : ecmAircraftList) {
			switch (ac.getEcmType()) {
			    case SPOT:
				//updateSpotEcmEffect();
				break;

			    case SWEEP:
				//updateSpotEcmEffect();
				break;

			    case BARRAGE_SYNC:
				//updateSpotEcmEffect();
				break;

			    case DECEPTION:
				updateDeceptionEcmEffect(ac,radarType.getRadarRange());
				break;

			    case CHAFF:
				updateChaffEcmEffect(ac, radarType.getRadarRange() );
				break;

			    case NONE:
				break;

			}
		    }
		    break;

		case SB:
		    break;

		case SLS:
		    break;

		case MTI:
		    break;

		case NONE:
		    updateEcmEffect();
		    break;
	    }
	}
    }

    public void updateEcmEffect() {
	for (Aircraft ac : ecmAircraftList) {
	    switch (ac.getEcmType()) {
		case SPOT:
		    updateSpotEcmEffect(ac);
		    break;

		case SWEEP:
		    updateSweepEcmEffect(ac);
		    break;

		case BARRAGE_SYNC:
		    updateSynBarrageEcmEffect(ac);
		    break;

		case DECEPTION:
		    updateDeceptionEcmEffect(ac,radarType.getRadarRange() );
		    break;

		case CHAFF:
		    updateChaffEcmEffect(ac, radarType.getRadarRange() );
		    break;

		case NONE:
		    break;

	    }
	}
    }

    public void updateEcmEffectForFA_EPM() {
	for (Aircraft ac : ecmAircraftList) {
	    switch (ac.getEcmType()) {
		case SPOT:
		    //updateSpotEcmEffect();
		    //ac.setEcmType(EcmType.NONE);
		    break;

		case SWEEP:
		    // updateSpotEcmEffect();
		    break;

		case BARRAGE_SYNC:
		    //updateSpotEcmEffect();
		    break;

		case DECEPTION:
		    //updateDeceptionEcmEffect(ac);
		    break;

		case CHAFF:
		    //updateChaffEcmEffect(ac);
		    break;

		case NONE:
		    break;

	    }
	}
    }

    public void updateSpotEcmEffect(Aircraft ac) {
	ecmDrawableList = new ArrayList<EcmDrawable>();
	float startAngle = 30;
	float arcAngle = 20;
	double yDiff = ac.getAircraftState().getLocation().getY() - radarState.getLocation().getY();
	double xDiff = ac.getAircraftState().getLocation().getX() - radarState.getLocation().getX();
	double angleInDegree = Math.toDegrees( Math.atan( (double)yDiff/xDiff) );
	
	//System.out.println("WIthout :"+angleInDegree+"*******");
	
	float radarPositionX = (int) (radarState.getLocation().getX() * HTB_MAIN.one_px_equivalent_naut);
	float radarPositionY = (int) (radarState.getLocation().getY() * HTB_MAIN.one_px_equivalent_naut);
	float radarRadius = (float) (getRadarType().getRadarRange() * HTB_MAIN.one_px_equivalent_naut);
	
//	float yDifference = ( ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) 
//		     - ( radarState.getLocation().getY()* HTB_MAIN.one_px_equivalent_naut );
//	float xDifference = ( ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut )
//		    -( radarState.getLocation().getX()* HTB_MAIN.one_px_equivalent_naut );
//	
//	double ratio = Math.abs( (double)yDifference/xDifference );
//	float sAngleInRad = (float) Math.atan(ratio);
//	float sAngleInDegree = (float) Math.toDegrees(sAngleInRad);\

	
	//************ Angle according to Moon vai
	double angleInDegreeNew = GeneralUtil.getHeadingWithOther(radarState.getLocation().getX(),radarState.getLocation().getY(),
		ac.getAircraftState().getLocation().getX(),ac.getAircraftState().getLocation().getY());
	//angleInDegreeNew = 270 - angleInDegreeNew;
	//System.out.println("According to moon vai: "+angleInDegreeNew+" and me: "+angleInDegree);
//	ArcEcm arcEcm = new ArcEcm((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (-angleInDegree), (int) (arcAngle));
	ArcEcm arcEcm = new ArcEcm((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (angleInDegreeNew), (int) (arcAngle),
		(int) (ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut ) ,
		(int) (ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) );

	ecmDrawableList.add(arcEcm);
	//g.fillArc((int)(radarPositionX-radarRadius), (int)(radarPositionY-radarRadius) , (int)(2*radarRadius), (int)(2*radarRadius), (int)(-angle), 20 );
    }
    public void updateSweepEcmEffect(Aircraft ac) {
	ecmDrawableList = new ArrayList<EcmDrawable>();
	float startAngle = 30;
	float arcAngle = 20;
	double yDiff = ac.getAircraftState().getLocation().getY() - radarState.getLocation().getY();
	double xDiff = ac.getAircraftState().getLocation().getX() - radarState.getLocation().getX();
	double angleInDegree = Math.toDegrees( Math.atan( (double)yDiff/xDiff) );
	
	System.out.println("WIthout :"+angleInDegree+"*******");
	
	float radarPositionX = (int) (radarState.getLocation().getX() * HTB_MAIN.one_px_equivalent_naut);
	float radarPositionY = (int) (radarState.getLocation().getY() * HTB_MAIN.one_px_equivalent_naut);
	float radarRadius = (float) (getRadarType().getRadarRange() * HTB_MAIN.one_px_equivalent_naut);
	
//	float yDifference = ( ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) 
//		     - ( radarState.getLocation().getY()* HTB_MAIN.one_px_equivalent_naut );
//	float xDifference = ( ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut )
//		    -( radarState.getLocation().getX()* HTB_MAIN.one_px_equivalent_naut );
//	
//	double ratio = Math.abs( (double)yDifference/xDifference );
//	float sAngleInRad = (float) Math.atan(ratio);
//	float sAngleInDegree = (float) Math.toDegrees(sAngleInRad);\

	
	//************ Angle according to Moon vai
	double angleInDegreeNew = GeneralUtil.getHeadingWithOther(radarState.getLocation().getX(),radarState.getLocation().getY(),
		ac.getAircraftState().getLocation().getX(),ac.getAircraftState().getLocation().getY());
	//angleInDegreeNew = 270 - angleInDegreeNew;
	//System.out.println("According to moon vai: "+angleInDegreeNew+" and me: "+angleInDegree);
//	ArcEcm arcEcm = new ArcEcm((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (-angleInDegree), (int) (arcAngle));
//	ArcEcm arcEcm = new ArcEcm((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (angleInDegreeNew), (int) (arcAngle),
//		(int) (ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut ) ,
//		(int) (ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) );
	SweepEcm sweepEcm = new SweepEcm((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (angleInDegreeNew), (int) (arcAngle),
		(int) (ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut ) ,
		(int) (ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) );

	ecmDrawableList.add(sweepEcm);
	//g.fillArc((int)(radarPositionX-radarRadius), (int)(radarPositionY-radarRadius) , (int)(2*radarRadius), (int)(2*radarRadius), (int)(-angle), 20 );
    }
    public void updateSynBarrageEcmEffect(Aircraft ac) {
	ecmDrawableList = new ArrayList<EcmDrawable>();
	float startAngle = 30;
	float arcAngle = 20;
	double yDiff = ac.getAircraftState().getLocation().getY() - radarState.getLocation().getY();
	double xDiff = ac.getAircraftState().getLocation().getX() - radarState.getLocation().getX();
	double angleInDegree = Math.toDegrees( Math.atan( (double)yDiff/xDiff) );
	
	System.out.println("WIthout :"+angleInDegree+"*******");
	
	float radarPositionX = (int) (radarState.getLocation().getX() * HTB_MAIN.one_px_equivalent_naut);
	float radarPositionY = (int) (radarState.getLocation().getY() * HTB_MAIN.one_px_equivalent_naut);
	float radarRadius = (float) (getRadarType().getRadarRange() * HTB_MAIN.one_px_equivalent_naut);
	
//	float yDifference = ( ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) 
//		     - ( radarState.getLocation().getY()* HTB_MAIN.one_px_equivalent_naut );
//	float xDifference = ( ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut )
//		    -( radarState.getLocation().getX()* HTB_MAIN.one_px_equivalent_naut );
//	
//	double ratio = Math.abs( (double)yDifference/xDifference );
//	float sAngleInRad = (float) Math.atan(ratio);
//	float sAngleInDegree = (float) Math.toDegrees(sAngleInRad);\

	
	//************ Angle according to Moon vai
	double angleInDegreeNew = GeneralUtil.getHeadingWithOther(radarState.getLocation().getX(),radarState.getLocation().getY(),
		ac.getAircraftState().getLocation().getX(),ac.getAircraftState().getLocation().getY());
	//angleInDegreeNew = 270 - angleInDegreeNew;
	//System.out.println("According to moon vai: "+angleInDegreeNew+" and me: "+angleInDegree);
//	ArcEcm arcEcm = new ArcEcm((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (-angleInDegree), (int) (arcAngle));
//	ArcEcm arcEcm = new ArcEcm((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (angleInDegreeNew), (int) (arcAngle),
//		(int) (ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut ) ,
//		(int) (ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) );
//	SyncBarrageEcm syncBarrageEcm = new SyncBarrageEcm((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (angleInDegreeNew), (int) (arcAngle),
//		(int) (ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut ) ,
//		(int) (ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) );
	if(toggle == 0)
	{
	    toggle = 1;
	    SyncBarrageEcm syncBarrageEcm = new SyncBarrageEcm((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (angleInDegreeNew), (int) (arcAngle),
		(int) (ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut ) ,
		(int) (ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) );
	    ecmDrawableList.add(syncBarrageEcm);
	}else if(toggle == 1)
	{
	    toggle = 0;
	    SyncBarrageEcm2 syncBarrageEcm2 = new SyncBarrageEcm2((int) (radarPositionX - radarRadius), (int) (radarPositionY - radarRadius), (int) (2 * radarRadius), (int) (2 * radarRadius), (int) (angleInDegreeNew), (int) (arcAngle),
		(int) (ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut ) ,
		(int) (ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut) );
	    ecmDrawableList.add(syncBarrageEcm2);
	}
	//ecmDrawableList.add(syncBarrageEcm);
	//g.fillArc((int)(radarPositionX-radarRadius), (int)(radarPositionY-radarRadius) , (int)(2*radarRadius), (int)(2*radarRadius), (int)(-angle), 20 );
    }

    public void updateDeceptionEcmEffect(Aircraft ac, double radarRange) {
	ecmDrawableList = new ArrayList<EcmDrawable>();
//	float startAngle = 30;
//	float arcAngle = 20;
	float radarPositionX = (int) (radarState.getLocation().getX() * HTB_MAIN.one_px_equivalent_naut);
	float radarPositionY = (int) (radarState.getLocation().getY() * HTB_MAIN.one_px_equivalent_naut);
//	float radarRadius = (float) (getRadarType().getRadarRange() 
//			 * HTB_MAIN.one_px_equivalent_naut);
	//ArcEcm arcEcm = new ArcEcm( (int)(radarPositionX-radarRadius), (int)(radarPositionY-radarRadius) , (int)(2*radarRadius), (int)(2*radarRadius), (int)(-startAngle), (int)(arcAngle));

	//ecmDrawableList.add(arcEcm);
	//g.fillArc((int)(radarPositionX-radarRadius), (int)(radarPositionY-radarRadius) , (int)(2*radarRadius), (int)(2*radarRadius), (int)(-angle), 20 );

	DeceptionEcm deceptionEcm = new DeceptionEcm((int) radarPositionX, (int) radarPositionY,
		(int) (ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut ),
		(int) (ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut), (int)(radarRange * HTB_MAIN.one_px_equivalent_naut) );
	ecmDrawableList.add(deceptionEcm);
    }

    public void updateChaffEcmEffect(Aircraft ac, double radarRange ) {
	ecmDrawableList = new ArrayList<EcmDrawable>();
//	float startAngle = 30;
//	float arcAngle = 20;
//	float radarPositionX = (int) (radarState.getLocation().getX() * HTB_MAIN.one_px_equivalent_naut);
//	float radarPositionY = (int) (radarState.getLocation().getY() * HTB_MAIN.one_px_equivalent_naut);
//	float radarRadius = (float) (getRadarType().getRadarRange() 
//			 * HTB_MAIN.one_px_equivalent_naut);
//	ArcEcm arcEcm = new ArcEcm( (int)(radarPositionX-radarRadius), (int)(radarPositionY-radarRadius) , (int)(2*radarRadius), (int)(2*radarRadius), (int)(-startAngle), (int)(arcAngle));
	float radarPositionX = (int) (radarState.getLocation().getX() * HTB_MAIN.one_px_equivalent_naut);
	float radarPositionY = (int) (radarState.getLocation().getY() * HTB_MAIN.one_px_equivalent_naut);
	
	ChaffEcm chaffEcm = new ChaffEcm((int) radarPositionX, (int) radarPositionY,
		(int) (ac.getAircraftState().getLocation().getX()* HTB_MAIN.one_px_equivalent_naut ),
		(int) (ac.getAircraftState().getLocation().getY()* HTB_MAIN.one_px_equivalent_naut), (int)(radarRange * HTB_MAIN.one_px_equivalent_naut) );
	ecmDrawableList.add(chaffEcm);
	//g.fillArc((int)(radarPositionX-radarRadius), (int)(radarPositionY-radarRadius) , (int)(2*radarRadius), (int)(2*radarRadius), (int)(-angle), 20 );
    }

    public void draw(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        Color c = g2d.getColor();
        
	double radarPositionX, radarPositionY, radarRect;
	radarPositionX = (getRadarState().getLocation().getX() * HTB_MAIN.one_px_equivalent_naut);
	radarPositionY = (getRadarState().getLocation().getY() * HTB_MAIN.one_px_equivalent_naut);
	radarRect = 10;

	radarPositionX -= radarRect / 2;
	radarPositionY -= radarRect / 2;


	
        g2d.draw(new Rectangle2D.Double(radarPositionX, radarPositionY, radarRect, radarRect));
	//g2d.drawRect(radarPositionX, radarPositionY, radarRect, radarRect);
        
        //HTB_MAIN.customDrawString(g, this.getRadarState().getRadarName(), new Point(radarPositionX - 5, radarPositionY - 17));
	g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
	
	//g2d.drawLine(
//        (int) (getRadarState().getLocation().getX() * HTB_MAIN.one_px_equivalent_naut),
//        (int) (getRadarState().getLocation().getY() * HTB_MAIN.one_px_equivalent_naut),
//        (int) (coneX * HTB_MAIN.one_px_equivalent_naut),
//        (int) (coneY * HTB_MAIN.one_px_equivalent_naut));
//
        g2d.draw(new Line2D.Double(
                new Point2D.Double(
                (getRadarState().getLocation().getX() * HTB_MAIN.one_px_equivalent_naut),
                (getRadarState().getLocation().getY() * HTB_MAIN.one_px_equivalent_naut)
                ),
                new Point2D.Double(
                (coneX * HTB_MAIN.one_px_equivalent_naut),
                (coneY * HTB_MAIN.one_px_equivalent_naut)
                )));
        /*
	HTB_MAIN.customDrawString(g, this.getRadarType().getRadarType(), new Point(radarPositionX - 5, radarPositionY - 17));
	g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

	g2d.drawLine((int) (radarState.getLocation().getX() * HTB_MAIN.one_px_equivalent_naut), (int) (radarState.getLocation().getY() * HTB_MAIN.one_px_equivalent_naut),
		(int) (coneX * HTB_MAIN.one_px_equivalent_naut),
		(int) (coneY * HTB_MAIN.one_px_equivalent_naut));

*/
	/*
	 for (Detected dt : detectedList) {
	 int aircraftPositionX, aircraftPositionY, aircraftRect;
	 aircraftPositionX = (int) dt.getAcPosX();
	 aircraftPositionY = (int) dt.getAcPosY();
	 aircraftRect = 6;
	    
	 aircraftPositionX -= aircraftRect/2;
	 aircraftPositionY -= aircraftRect/2;
	    
	 g2d.drawRect(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect);
	 }
	 * */

	//Color c = g.getColor();

	
	if(getAircraftPathShowOption()==AircraftPathShowOption.DefaultPath)
	{
	    g2d.setColor(Color.GREEN);
	    aircraftListForPath.draw(g2d);
	}
	
	else if(getAircraftPathShowOption()==AircraftPathShowOption.FullPath)
	{
	    int rectangleSize = 4;
	    g2d.setColor(new Color(10, 102, 109));
	    for(Location location: this.getPathAircraft())
	    {		
		//g2d.fillRect(Math.round(location.getX()*HTB_MAIN.one_px_equivalent_naut)-rectangleSize/2, Math.round(location.getY()*HTB_MAIN.one_px_equivalent_naut)-rectangleSize/2, rectangleSize, rectangleSize);
                g2d.draw(new Rectangle2D.Double((location.getX()*HTB_MAIN.one_px_equivalent_naut)-rectangleSize/2,
                        (location.getY()*HTB_MAIN.one_px_equivalent_naut)-rectangleSize/2,
                        rectangleSize,
                        rectangleSize
                        ));
	    }
	}
	
	/*
	 for (Object ot : getDetectedMap().values()) 
	 {
	 Detected dt = (Detected) ot;
	 dt.drawLocation(g);
	 }
	 */

	/*
	 for (Object ot : getDetectedMap().values()) 
	 {
	 Detected dt = (Detected) ot;
	 dt.getAircraft().getAircraftState().drawPathDefault(g, Color.WHITE);
	 }
	 */

	for (Object ot : getDetectedMap().values()) 
	{
	    Detected dt = (Detected) ot;
	    double aircraftPositionX, aircraftPositionY, aircraftRect;
	    aircraftPositionX = (dt.getAcPosX() * HTB_MAIN.one_px_equivalent_naut);
	    aircraftPositionY = (dt.getAcPosY() * HTB_MAIN.one_px_equivalent_naut);
	    aircraftRect = 8;

	    aircraftPositionX -= aircraftRect / 2;
	    aircraftPositionY -= aircraftRect / 2;

	    if(getAircraftPathShowOption() == AircraftPathShowOption.Blip1Path)
	    {
                if(dt.getAircraft().isIffSignalCheck())
                {                    
                    g2d.setColor(Color.BLACK);
                    //g2d.drawRect(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect);
                    g2d.draw(new Rectangle2D.Double(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect));
                    System.out.println("why not");
                }
                else
                {
                    g2d.setColor(Color.BLACK);
                    //g2d.fillRect(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect);
                    Rectangle2D rect = new Rectangle2D.Double(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect);
                    //g2d.draw(new Rectangle2D.Double(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect));
                    g2d.fill(rect);
                }                
	    }
	    
            Color color = null;
	    
            try
            {
                color = dt.getAircraft().getAircraftState().getAircraftIdentity().getColor();
            }
            catch(NullPointerException npEx)
            {
                color = Color.BLACK;
            }	 
            
            if(dt.getAircraft().isIffSignalCheck())
            {
                //if(iffControl == 1)
               // {         
                g2d.setColor(color);
                //g2d.drawRect(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect);
                g2d.draw(new Rectangle2D.Double(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect));
                //}
                

            }
            else
            {
                g2d.setColor(color);
                //g2d.fillRect(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect);
                g2d.draw(new Rectangle2D.Double(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect));
            }
	    
            //g.setColor(color);
            //g.fillRect(aircraftPositionX, aircraftPositionY, aircraftRect, aircraftRect); 	
            
            
            int modeCheck;
            double yPosition = aircraftPositionY + 2;
            double stringPositionX = aircraftPositionX - 40;;
	    double stringPositionY = yPosition + 5;
            
            try
            {
                modeCheck = dt.getAircraft().getAircraftState().getModeIdentity().getMode();
                if(modeCheck == 1)
                {
                       g2d.setColor(new Color(165, 42, 42));
                       g.drawArc((int)stringPositionX+40, (int)stringPositionY, 15,8 ,0,-90);
                       g.drawArc((int)stringPositionX+42, (int)stringPositionY+2, 20,10 ,0,-90);

                }
                if(modeCheck == 2)
                {
                        g.setColor(new Color(165, 42, 42));
                        g.drawArc((int)stringPositionX+40, (int)stringPositionY, 15,8 ,0,-90);

                }
                if(modeCheck == 3)
                {

                       g.setColor(new Color(165, 42, 42));
                       g.drawArc((int)stringPositionX+40, (int)stringPositionY, 15,8 ,0,-90);
    
                }
                if(modeCheck == 4)
                {
   
                        g.setColor(Color.BLACK);
                        HTB_MAIN.customDrawString(g2d, " "+dt.getHeight(), new Point((int)stringPositionX+40, (int)stringPositionY));
                }
            
           
            }
            catch(Exception ex)
            {
                modeCheck = 0;
            }
            
	    g.setColor(Color.BLACK);

            g.setColor(ObjectColors.RADARTEXT.getColor());	    
	    
	    if (HTB_MAIN.radarACInfoSelection.isHeight()) 
	    {		
		HTB_MAIN.customDrawString(g2d, "" + dt.getHeight(), new Point((int)stringPositionX, (int)stringPositionY));
		stringPositionY += 14;
	    }

	    if (HTB_MAIN.radarACInfoSelection.isHeading()) {
                
		HTB_MAIN.customDrawString(g2d, "" + dt.getHeading(), new Point((int)stringPositionX, (int)stringPositionY));
		stringPositionY += 14;
	    }

	    if (HTB_MAIN.radarACInfoSelection.isSpeed()) {

		HTB_MAIN.customDrawString(g2d, "" + dt.getSpeed(), new Point((int)stringPositionX, (int)stringPositionY));
		stringPositionY += 14;
	    }

	    if (HTB_MAIN.radarACInfoSelection.isCallSign()) {
		HTB_MAIN.customDrawString(g2d, "" + dt.getAircraft().getAircraftState().getCallSign(), new Point((int)stringPositionX, (int)stringPositionY));
	    }

	    g.setColor(Color.BLACK);
	    
	    if(HTB_MAIN.iFFOptionSelection.isLocation())
	    {
                
		HTB_MAIN.customDrawString(g2d, aircraftPositionX+" , "+aircraftPositionY  , new Point((int)stringPositionX, (int)stringPositionY));
                stringPositionY +=14;
                
	    }
	    if(HTB_MAIN.iFFOptionSelection.isFuelStatus())
	    {
                float fuelRatio = dt.getAircraft().getAircraftState().getFuelStatus()/dt.getAircraft().getAircraftType().getFuelCapacity();
                if(fuelRatio>0.05)
                {
                    HTB_MAIN.customDrawString(g2d, " "+dt.getAircraft().getAircraftState().getFuelStatus(), new Point((int)stringPositionX, (int)stringPositionY));
                    stringPositionY +=14;
                }
                else
                {
                    HTB_MAIN.customDrawString(g2d, "Danger   "+dt.getAircraft().getAircraftState().getFuelStatus(), new Point((int)stringPositionX, (int)stringPositionY));
                    stringPositionY +=14;
                }
               
	    }
	    
	    if(HTB_MAIN.iFFOptionSelection.isAltimeter())
	    {
                
		HTB_MAIN.customDrawString(g2d, "1013.2"  , new Point((int)stringPositionX, (int)stringPositionY));
                stringPositionY +=14;
                
	    }
	    
	    if(HTB_MAIN.iFFOptionSelection.isModeC())
	    {
               HTB_MAIN.customDrawString(g2d, " "+dt.getHeight(), new Point((int)stringPositionX, (int)stringPositionY));
                stringPositionY +=14; 
                
	    }
	    
	    if(HTB_MAIN.iFFOptionSelection.isMode3A())
	    {
                if(!dt.getAircraft().getAircraftType().getTypename().toString().equals("F16") && !dt.getAircraft().getAircraftType().getTypename().toString().equals("Mig31"))
                {
		HTB_MAIN.customDrawString(g2d, "Mode 3A"  , new Point((int)stringPositionX, (int)stringPositionY));
                stringPositionY +=14;
                }
                
	    }
	    
	    if(HTB_MAIN.iFFOptionSelection.isMode2())
	    {
                if(dt.getAircraft().getAircraftType().getTypename().toString().equals("Mig31"))
                {
		HTB_MAIN.customDrawString(g2d, "Mode 2"  , new Point((int)stringPositionX, (int)stringPositionY));
                stringPositionY +=14;
                }
	    }
            
            if(HTB_MAIN.iFFOptionSelection.isMode1())
	    {
                if(dt.getAircraft().getAircraftType().getTypename().toString().equals("F16"))
                {
		    HTB_MAIN.customDrawString(g2d, "Mode 1"  , new Point((int)stringPositionX, (int)stringPositionY));
		    stringPositionY +=14;
                }
	    }
                
               
              
               
              
            	    

	}//end for

	// autolock draws

	if (autoLockGround != null) {
	    autoLockGround.draw(g);
	}

	if (autoLock != null) {
	    autoLock.draw(g);
	}

	if (aiRadar.isAssignedToAnyAircraft()) {
	    aiRadar.draw(g);
	}
	//added by ratan
	//radarPositionX  -- radar center
	//radarPositionY
	radarPositionX += radarRect / 2;
	radarPositionY += radarRect / 2;
	float radarRadius = (float) (getRadarType().getRadarRange()
		* HTB_MAIN.one_px_equivalent_naut);
	float angle = 30;

//	g.fillArc((int)radarPositionX, (int)radarPositionY , (int)(2*radarRadius), (int)(2*radarRadius), (int)angle, 20 );
//	g.fillArc((int)radarPositionX, (int)radarPositionY , (int)(radarRadius), (int)(radarRadius), (int)angle, 20 );
//	g.fillArc((int)radarPositionX, (int)radarPositionY , (int)(3*radarRadius), (int)(3*radarRadius), (int)angle, 20 );
	//g.fillArc((int)(radarPositionX-radarRadius), (int)(radarPositionY-radarRadius) , (int)(2*radarRadius), (int)(2*radarRadius), (int)(-angle), 20 );


	//setEcmEffect();
	if (ecmAircraftList.size() != 0) {
	    showEcmEffect(g);
	    
	}

	//end of addition by ratan

	//
        g.setColor(c);
	
	
    }
    
    
    public void drawRadarRange(Graphics2D g, double radarX, double radarY)
    {
	g.setColor(new Color(0, 128, 64));
	
	g.setStroke(new BasicStroke(3));
	double innerCircleRadius =  (this.getRadarType().getRadarRange() * HTB_MAIN.one_px_equivalent_naut / 3);
	double middleCircleRadius =  (2 * this.getRadarType().getRadarRange() * HTB_MAIN.one_px_equivalent_naut / 3);
	double outerCircleRadius = (this.getRadarType().getRadarRange() * HTB_MAIN.one_px_equivalent_naut);

	//
	g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);



	double circleCenterX = radarX - innerCircleRadius;
	double circleCenterY = radarY - innerCircleRadius;

        Ellipse2D.Double ellipse2D
                    = new Ellipse2D.Double(circleCenterX, circleCenterY, innerCircleRadius * 2, innerCircleRadius * 2);
	//g.drawOval(circleCenterX, circleCenterY, innerCircleRadius * 2, innerCircleRadius * 2);
        g.draw(ellipse2D);

	circleCenterX = radarX - outerCircleRadius;
	circleCenterY = radarY - outerCircleRadius;

        Ellipse2D.Double ellipse2Di
                    = new Ellipse2D.Double(circleCenterX, circleCenterY, outerCircleRadius * 2, outerCircleRadius * 2);
	//g2d.drawOval(circleCenterX, circleCenterY, outerCircleRadius * 2, outerCircleRadius * 2);

        g.draw(ellipse2Di);

	/* some gradient experiment
	 RadialGradientPaint p = new RadialGradientPaint(new Point2D.Float(radarX,radarY), outerCircleRadius*2, new float[]{0,.5f},new Color[]{Color.GREEN, Color.BLACK} );
	 g2d.setPaint(p);
	 g2d.fillOval(circleCenterX, circleCenterY , outerCircleRadius*2, outerCircleRadius*2);
	 */

	circleCenterX = radarX - middleCircleRadius;
	circleCenterY = radarY - middleCircleRadius;

        Ellipse2D.Double ellipse2Di1
                    = new Ellipse2D.Double(circleCenterX, circleCenterY, middleCircleRadius * 2, middleCircleRadius * 2);
	//g2d.drawOval(circleCenterX, circleCenterY, middleCircleRadius * 2, middleCircleRadius * 2);

        g.draw(ellipse2Di1);
	g.setStroke(new BasicStroke(1));
    }

    public void addHTBParent(HTB_MAIN htbParent) {
	//this.HTBParent = htbParent;
    }

    public boolean isOutOfRange(Aircraft ac) {
	//double distance = GeneralUtil.distance(getRadarState().getLocation().getX(), getRadarState().getLocation().getY(), getRadarState().getLocation().getZ(),
		//ac.getAircraftState().getLocation().getX(), ac.getAircraftState().getLocation().getY(), ac.getAircraftState().getLocation().getZ());
        double distance = GeneralUtil.distance2D(getRadarState().getLocation().getX(), getRadarState().getLocation().getY(), ac.getAircraftState().getLocation().getX(), ac.getAircraftState().getLocation().getY());
	if (distance > getRadarType().getRadarRange()) {
	    return true;
	}
	return false;
    }
    
    public double getX(){
        return getRadarState().getLocation().getX();
    }
    
    public double getY(){
        return getRadarState().getLocation().getY();
        
    }

    /**
     * @return the autoLock
     */
    public AutoLock getAutoLock() {
	return autoLock;
    }

    /**
     * @return the detectedMap
     */
    public HashMap getDetectedMap() {
	return detectedMap;
    }

    /**
     * @return the pathAircraft
     */
    public List<Location> getPathAircraft() {
	return pathAircraft;
    }

    /**
     * @param pathAircraft the pathAircraft to set
     */
    public void setPathAircraft(List<Location> pathAircraft) {
	this.pathAircraft = pathAircraft;
    }

    /**
     * @return the radarType
     */
    public RadarType getRadarType() {
	return radarType;
    }

    /**
     * @return the autoLockGround
     */
    public AutoLockGround getAutoLockGround() {
	return autoLockGround;
    }

    /**
     * @return the aiRadar
     */
    public AIRadar getAiRadar() {
	return aiRadar;
    }

    // this method is for testing purpose
    public static void main(String a[]) {
    }    

    /**
     * @return the pathShowOption
     */
    

    /**
     * @param pathShowOption the pathShowOption to set
     */
    

    /**
     * @return the radarState
     */
    public RadarState getRadarState() {
        return radarState;
    }

    public void notifyRadar(Aircraft ac) {
	if (!isOutOfRange(ac)) {
	    ecmAircraftList.add(ac);
	}

    }

    public void notifyRadarForEpm(Aircraft ac) {
	if (!isOutOfRange(ac)) {
	    // ecmAircraftList.remove(ac);
	}

    }

    public void showEcmEffect(Graphics g) {
	for (EcmDrawable ecmDrawable : ecmDrawableList) {
	    ecmDrawable.draw(g, epmType);

	}
    }

    public EpmType getEpmType() {
	return epmType;
    }

    public void setEpmType(EpmType epmType) {
	this.epmType = epmType;
        GeneralUtil.UpdateGameScene(HTB_MAIN.gameScene);
        
    }

    public void removeECMAirCraft(Aircraft ac) {
	//throw new UnsupportedOperationException("Not yet implemented");
	if (!isOutOfRange(ac)) {
	    ecmAircraftList.remove(ac);
	    if (ecmAircraftList.size() == 0) {
		ecmDrawableList = new ArrayList<EcmDrawable>();
	    }
	}
    }

    /**
     * @return the radarContinue
     */
    public boolean isRadarContinue() {
	return radarContinue;
    }

    /**
     * @param radarContinue the radarContinue to set
     */
    public void setRadarContinue(boolean radarContinue) {
	this.radarContinue = radarContinue;
    }

    /**
     * @return the aircraftPathShowOption
     */
    public AircraftPathShowOption getAircraftPathShowOption() {
	return aircraftPathShowOption;
    }

    /**
     * @param aircraftPathShowOption the aircraftPathShowOption to set
     */
    public void setAircraftPathShowOption(AircraftPathShowOption aircraftPathShowOption) {
	this.aircraftPathShowOption = aircraftPathShowOption;
    }
}
//End of Radar class